/**
 * 渲染命令执行器
 * 
 * 职责：
 * 1. 执行渲染相关的命令
 * 2. 操作 ViewComponent 更新视图
 * 3. 处理动画、特效、音效等
 * 
 * @author AI Assistant
 * @date 2025-11-26
 */

import { ecs } from "../../../core/ecs/ECS";
import { ViewComponent } from "../component/ViewComponent";
import { Vec3, Color, Node } from "cc";
import { CommandType, ICommand, ICommandExecutor } from "./CommandQueue";

/**
 * 渲染命令执行器
 */
export class RenderCommandExecutor implements ICommandExecutor {
    /**
     * 检查是否可以执行该命令
     */
    canExecute(commandType: CommandType): boolean {
        const supportedCommands = [
            CommandType.SET_POSITION,
            CommandType.SET_ROTATION,
            CommandType.SET_SCALE,
            CommandType.SET_VISIBLE,
            CommandType.SET_ACTIVE,
            CommandType.PLAY_ANIMATION,
            CommandType.STOP_ANIMATION,
            CommandType.PAUSE_ANIMATION,
            CommandType.SET_SPRITE_FRAME,
            CommandType.SET_SPRITE_COLOR,
            CommandType.SET_SPRITE_OPACITY,
            CommandType.SET_LABEL_TEXT,
            CommandType.SET_LABEL_COLOR,
            CommandType.DESTROY_NODE
        ];
        
        return supportedCommands.includes(commandType);
    }
    
    /**
     * 执行命令
     */
    execute(command: ICommand): any {
        // 获取实体
        const entity = ecs.getEntityByEid(command.entityId);
        if (!entity) {
            throw new Error(`实体 ${command.entityId} 不存在`);
        }
        
        // 获取 ViewComponent
        const viewComp = entity.get(ViewComponent);
        if (!viewComp) {
            throw new Error(`实体 ${command.entityId} 没有 ViewComponent`);
        }
        
        // 根据命令类型执行
        switch (command.type) {
            case CommandType.SET_POSITION:
                return this.setPosition(viewComp, command.params);
                
            case CommandType.SET_ROTATION:
                return this.setRotation(viewComp, command.params);
                
            case CommandType.SET_SCALE:
                return this.setScale(viewComp, command.params);
                
            case CommandType.SET_VISIBLE:
                return this.setVisible(viewComp, command.params);
                
            case CommandType.SET_ACTIVE:
                return this.setActive(viewComp, command.params);
                
            case CommandType.PLAY_ANIMATION:
                return this.playAnimation(viewComp, command.params);
                
            case CommandType.STOP_ANIMATION:
                return this.stopAnimation(viewComp, command.params);
                
            case CommandType.PAUSE_ANIMATION:
                return this.pauseAnimation(viewComp, command.params);
                
            case CommandType.SET_SPRITE_FRAME:
                return this.setSpriteFrame(viewComp, command.params);
                
            case CommandType.SET_SPRITE_COLOR:
                return this.setSpriteColor(viewComp, command.params);
                
            case CommandType.SET_SPRITE_OPACITY:
                return this.setSpriteOpacity(viewComp, command.params);
                
            case CommandType.SET_LABEL_TEXT:
                return this.setLabelText(viewComp, command.params);
                
            case CommandType.SET_LABEL_COLOR:
                return this.setLabelColor(viewComp, command.params);
                
            case CommandType.DESTROY_NODE:
                return this.destroyNode(viewComp, command.params);
                
            default:
                throw new Error(`不支持的命令类型: ${command.type}`);
        }
    }
    
    // ========== 节点操作 ==========
    
    /**
     * 设置位置
     * @param params { x: number, y: number, z?: number } 或 Vec3
     */
    private setPosition(viewComp: ViewComponent, params: any): void {
        if (!viewComp.node) return;
        
        if (params instanceof Vec3) {
            viewComp.node.setPosition(params);
        } else {
            const { x, y, z = 0 } = params;
            viewComp.node.setPosition(x, y, z);
        }
    }
    
    /**
     * 设置旋转
     * @param params { x: number, y: number, z: number } 欧拉角
     */
    private setRotation(viewComp: ViewComponent, params: any): void {
        if (!viewComp.node) return;
        
        const { x = 0, y = 0, z = 0 } = params;
        viewComp.node.setRotationFromEuler(x, y, z);
    }
    
    /**
     * 设置缩放
     * @param params { x: number, y: number, z?: number } 或 number（统一缩放）
     */
    private setScale(viewComp: ViewComponent, params: any): void {
        if (!viewComp.node) return;
        
        if (typeof params === 'number') {
            viewComp.node.setScale(params, params, params);
        } else {
            const { x, y, z = 1 } = params;
            viewComp.node.setScale(x, y, z);
        }
    }
    
    /**
     * 设置可见性
     * @param params { visible: boolean }
     */
    private setVisible(viewComp: ViewComponent, params: any): void {
        const visible = params.visible ?? params;
        viewComp.setVisible(visible);
    }
    
    /**
     * 设置激活状态
     * @param params { active: boolean }
     */
    private setActive(viewComp: ViewComponent, params: any): void {
        if (!viewComp.node) return;
        
        const active = params.active ?? params;
        viewComp.node.active = active;
    }
    
    // ========== 动画操作 ==========
    
    /**
     * 播放动画
     * @param params { name: string, loop?: boolean }
     */
    private playAnimation(viewComp: ViewComponent, params: any): void {
        const { name, loop = false } = params;
        viewComp.playAnimation(name, loop);
    }
    
    /**
     * 停止动画
     */
    private stopAnimation(viewComp: ViewComponent, params: any): void {
        viewComp.stopAnimation();
    }
    
    /**
     * 暂停动画
     */
    private pauseAnimation(viewComp: ViewComponent, params: any): void {
        if (viewComp.animation) {
            viewComp.animation.pause();
        }
    }
    
    // ========== Sprite 操作 ==========
    
    /**
     * 设置 Sprite Frame
     * @param params { spriteFrame: SpriteFrame }
     */
    private setSpriteFrame(viewComp: ViewComponent, params: any): void {
        if (!viewComp.sprite) {
            console.warn('[RenderCommandExecutor] 没有 Sprite 组件');
            return;
        }
        
        viewComp.sprite.spriteFrame = params.spriteFrame || params;
    }
    
    /**
     * 设置 Sprite 颜色
     * @param params { color: Color } 或 { r, g, b, a }
     */
    private setSpriteColor(viewComp: ViewComponent, params: any): void {
        if (!viewComp.sprite) {
            console.warn('[RenderCommandExecutor] 没有 Sprite 组件');
            return;
        }
        
        if (params instanceof Color) {
            viewComp.sprite.color = params;
        } else {
            const { r, g, b, a = 255 } = params;
            viewComp.sprite.color = new Color(r, g, b, a);
        }
    }
    
    /**
     * 设置 Sprite 透明度
     * @param params { opacity: number } 0-255
     */
    private setSpriteOpacity(viewComp: ViewComponent, params: any): void {
        if (!viewComp.sprite) {
            console.warn('[RenderCommandExecutor] 没有 Sprite 组件');
            return;
        }
        
        const opacity = params.opacity ?? params;
        const color = viewComp.sprite.color;
        viewComp.sprite.color = new Color(color.r, color.g, color.b, opacity);
    }
    
    // ========== Label 操作 ==========
    
    /**
     * 设置 Label 文本
     * @param params { text: string }
     */
    private setLabelText(viewComp: ViewComponent, params: any): void {
        if (!viewComp.label) {
            console.warn('[RenderCommandExecutor] 没有 Label 组件');
            return;
        }
        
        viewComp.label.string = params.text ?? params;
    }
    
    /**
     * 设置 Label 颜色
     * @param params { color: Color } 或 { r, g, b, a }
     */
    private setLabelColor(viewComp: ViewComponent, params: any): void {
        if (!viewComp.label) {
            console.warn('[RenderCommandExecutor] 没有 Label 组件');
            return;
        }
        
        if (params instanceof Color) {
            viewComp.label.color = params;
        } else {
            const { r, g, b, a = 255 } = params;
            viewComp.label.color = new Color(r, g, b, a);
        }
    }
    
    // ========== 节点生命周期 ==========
    
    /**
     * 销毁节点
     * @param params { immediate?: boolean }
     */
    private destroyNode(viewComp: ViewComponent, params: any): void {
        const immediate = params?.immediate ?? false;
        viewComp.destroyNode(immediate);
    }
}

/**
 * 导出渲染命令执行器实例
 */
export const renderCommandExecutor = new RenderCommandExecutor();

